package cn.rkylin.oms.warehouse.stock.controller;

import cn.rkylin.core.controller.ApolloController;
import cn.rkylin.oms.common.context.CurrentUser;
import cn.rkylin.oms.common.context.WebContextFactory;
import cn.rkylin.oms.common.utils.LogUtil;
import cn.rkylin.oms.system.project.vo.ProjectVO;
import cn.rkylin.oms.system.stockpush.domain.StockFmla;
import cn.rkylin.oms.system.stockpush.service.IStockPushService;
import cn.rkylin.oms.system.storage.service.IStorService;
import cn.rkylin.oms.system.storage.vo.StorVO;
import cn.rkylin.oms.warehouse.stock.dao.IStockDAO;
import cn.rkylin.oms.warehouse.stock.service.IStockService;
import cn.rkylin.oms.warehouse.stock.vo.BatchStockVO;
import cn.rkylin.oms.warehouse.stock.vo.StockVO;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageInfo;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 库存控制类
 *
 * @author liming
 * @date 2017/10/16
 */
@Controller
@RequestMapping("/stock")
public class StockController extends ApolloController {

    private static final Log logger = LogFactory.getLog(StockController.class);

    @Autowired
    public IStockService stockService;

    @Autowired
    private LogUtil logUtil;
    @Autowired
    private IStockPushService stockPushService;
    /**
     * storService:仓库服务层.
     */
    @Autowired
    private IStorService storService;

    /**
     * 根据项目id获取仓库信息
     *
     * @param
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/getStor")
    public Map<String, Object> getStor() {
        logger.info(String.format("获取仓库信息：/stock/getStor"));
        // 用于返回值的json对象
        Map<String, Object> returnMap = new HashMap<String, Object>();
        try {
            // 获取当前登录人
            CurrentUser currentUser = WebContextFactory.getWebContext().getCurrentUser();
            if (currentUser == null) {
                return getFailedMap("查询当前登录人失败");
            }
            // 获取当前登录人所属项目
            String projectId = currentUser.getCurrentProject().getPrjId();
            // 根据项目id获取仓库信息
            List<StorVO> storList = storService.findByProjectId(projectId);
            if (null != storList) {
                returnMap = getSuccessMap("查询仓库信息完成");
                returnMap.put(RETURN_DATA, storList);
            }
        } catch (Exception e) {
            logger.error(e.getMessage());
            returnMap = getFailedMap(e.getMessage());
        }
        return returnMap;
    }

    /**
     * 根据项目id获取仓库信息
     *
     * @param
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/getExtStor")
    public Map<String, Object> getExtStor() {
        logger.info(String.format("获取仓库信息：/stock/getStor"));
        // 用于返回值的json对象
        Map<String, Object> returnMap = new HashMap<String, Object>();
        try {
            // 获取当前登录人
            CurrentUser currentUser = WebContextFactory.getWebContext().getCurrentUser();
            if (currentUser == null) {
                return getFailedMap("查询当前登录人失败");
            }
            // 获取当前登录人所属项目
            String projectId = currentUser.getCurrentProject().getPrjId();
            // 根据项目id获取仓库信息
            List<StorVO> storList = storService.findByProjectIdExt(projectId);
            if (null != storList) {
                returnMap = getSuccessMap("查询仓库信息完成");
                returnMap.put(RETURN_DATA, storList);
            }
        } catch (Exception e) {
            logger.error(e.getMessage());
            returnMap = getFailedMap(e.getMessage());
        }
        return returnMap;
    }

    /**
     * 根据项目id获取仓库信息(本地仓)
     *
     * @param
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/getStorLocal")
    public Map<String, Object> getStorLocal() {
        logger.info(String.format("获取仓库信息：/stock/getStorLocal"));
        // 用于返回值的json对象
        Map<String, Object> returnMap = new HashMap<String, Object>();
        try {
            // 获取当前登录人
            CurrentUser currentUser = WebContextFactory.getWebContext().getCurrentUser();
            if (currentUser == null) {
                return getFailedMap("查询当前登录人失败");
            }
            // 获取当前登录人所属项目
            String projectId = currentUser.getCurrentProject().getPrjId();
            // 根据项目id获取仓库信息
            List<StorVO> storList = storService.findByProjectIdLocal(projectId);
            if (null != storList) {
                returnMap = getSuccessMap("查询仓库信息完成");
                returnMap.put(RETURN_DATA, storList);
            }
        } catch (Exception e) {
            logger.error(e.getMessage());
            returnMap = getFailedMap(e.getMessage());
        }
        return returnMap;
    }

    /**
     * 根据项目id获取仓库信息(菜鸟)
     *
     * @param
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/getStorCainiao")
    public Map<String, Object> getStorCainiao() {
        logger.info(String.format("获取仓库信息：/stock/getStorCainiao"));
        // 用于返回值的json对象
        Map<String, Object> returnMap = new HashMap<String, Object>();
        try {
            // 获取当前登录人
            CurrentUser currentUser = WebContextFactory.getWebContext().getCurrentUser();
            if (currentUser == null) {
                return getFailedMap("查询当前登录人失败");
            }
            // 获取当前登录人所属项目
            String projectId = currentUser.getCurrentProject().getPrjId();
            // 根据项目id获取仓库信息
            List<StorVO> storList = storService.findByProjectIdCainiao(projectId);
            if (null != storList) {
                returnMap = getSuccessMap("查询仓库信息完成");
                returnMap.put(RETURN_DATA, storList);
            }
        } catch (Exception e) {
            logger.error(e.getMessage());
            returnMap = getFailedMap(e.getMessage());
        }
        return returnMap;
    }

    /**
     * getStockInfo:根据查询条件获取库存信息列表. <br/>
     *
     * @param quickSearch
     * @param start
     * @param length
     * @param storId
     * @return
     * @throws Exception
     */
    @ResponseBody
    @RequestMapping(value = "/getStockInfo")
    public Map<String, Object> getStockInfo(String quickSearch, @RequestParam(required = false, defaultValue = "0") int start,
                                            @RequestParam(required = false, defaultValue = "10") int length, String storId) throws Exception {
        logger.info("查询库存信息：/stock/getStockInfo");
        Map<String, Object> returnMap = new HashMap<>();

        StockVO queryParamVO = new StockVO();

        if (StringUtils.isBlank(quickSearch) && StringUtils.isBlank(storId)) {
            returnMap = getSuccessMap("查询库存信息成功");
            returnMap.put(RECORDS_FILTERED, 0);
            returnMap.put(RECORDS_TOTAL, 0);
            returnMap.put(RETURN_DATA, new ArrayList<StockVO>());
            return returnMap;
        }
        // 获取当前登录人
        CurrentUser currentUser = WebContextFactory.getWebContext().getCurrentUser();
        if (currentUser == null) {
            return getFailedMap("查询当前登录人失败");
        }
        // 获取当前登录人所属项目
        String projectId = currentUser.getCurrentProject().getPrjId();
        if (StringUtils.isBlank(projectId) || currentUser.getProjectMap() == null || currentUser.getProjectMap().size() <= 0) {
            return getFailedMap("查询当前登录人所属项目失败");
        }
        // 设置项目id
        queryParamVO.setPrjId(projectId);

        String entId = null;
        // 找前台选择的项目，对应的企业（这种做法是为了适应，用户对应到多个企业下的情况。）
        for (ProjectVO project : currentUser.getProjectMap().values()) {
            if (project.getPrjId().equalsIgnoreCase(projectId)) {
                entId = project.getEntId();
            }
        }
        queryParamVO.setEntId(entId);
        // 根据项目ID获取库存公式列表. 通常情况下，一个项目下只有一个库存计算公式
        StockFmla stockFmla = stockPushService.getStockFmlaByProjectId(projectId);

        // 仓库Id
        if (StringUtils.isNotBlank(storId)) {
            if ("all".equals(storId)) {
                List<String> idArray = new ArrayList<String>();
                // 根据项目id获取仓库信息
                List<StorVO> storList = storService.findByProjectId(projectId);
                for (StorVO storVO : storList) {
                    idArray.add(storVO.getStorId());
                }
                queryParamVO.setIdArray(idArray);
            } else {
                queryParamVO.setStorId(storId);
            }
        }
        // 快速查询
        if (quickSearch != null && StringUtils.isNotEmpty(quickSearch)) {
            quickSearch = URLDecoder.decode(quickSearch, "UTF-8");
            if (StringUtils.isNotEmpty(quickSearch)) {
                queryParamVO.setQuickSearch(quickSearch);
            }
        }

        Map<String, String> replaceFieldsMap = new HashMap<String, String>();
        if (null != stockFmla && "ext".equals(stockFmla.getStockValMode())) {
            replaceFieldsMap.put("available", "a.sell_count-a.allot_qty-a.freeze_qty-a.reserve_qty- CASE WHEN b.unallot_qty IS NULL THEN 0 ELSE b.unallot_qty END ");
            replaceFieldsMap.put("canallotQty", "a.sell_count-a.allot_qty-a.freeze_qty-a.reserve_qty");
            replaceFieldsMap.put("junkCanallotQty", "a.junk_count - a.junk_allot_qty");
        } else {
            replaceFieldsMap.put("available", "a.stock_qty-a.allot_qty-a.freeze_qty-a.reserve_qty-a.logic_stockout_qty- CASE WHEN b.unallot_qty IS NULL THEN 0 ELSE b.unallot_qty END");
            replaceFieldsMap.put("canallotQty", "a.stock_qty-a.allot_qty-a.freeze_qty-a.reserve_qty-a.logic_stockout_qty");
            replaceFieldsMap.put("junkCanallotQty", "a.junk_qty-a.junk_allot_qty");
        }
        // 排序语句生成
        String orderStatement = getOrderString(IStockDAO.class.getName(), "pageSelectStock", replaceFieldsMap);

        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        boolean orderFlag = true;
        for (int i = 0; orderFlag; i++) {
            // 排序的列号
            String order = request.getParameter("order[" + i + "][column]");
            // 排序的顺序asc or desc
            String orderDir = request.getParameter("order[" + i + "][dir]");
            // 排序的列名
            String orderColumn = request.getParameter("columns[" + order + "][data]");

            if (StringUtils.isEmpty(order) || StringUtils.isEmpty(orderDir) || StringUtils.isEmpty(orderColumn)) {
                orderFlag = false;
            } else {
                // 处理转义字段
                if (replaceFieldsMap != null && replaceFieldsMap.size() > 0) {
                    for (String replaceItem : replaceFieldsMap.keySet()) {
                        if (orderColumn.equals(replaceItem)) {
                            orderStatement = replaceFieldsMap.get(orderColumn) + " " + orderDir;
                            break;
                        }
                    }
                }
            }
        }
        if (StringUtils.isNotEmpty(orderStatement)) {
            queryParamVO.setOrderBy(orderStatement);
        }
        // 处理分页信息
        if (length == -1) {
            length = Integer.MAX_VALUE;
        }
        int page = start / length + 1;

        // 执行查询
        PageInfo<StockVO> stockVOList = stockService.queryStockList(page, length, queryParamVO);

        if (null != stockVOList) {
            if (null != stockFmla && "ext".equals(stockFmla.getStockValMode())) {
                for (int i = 0; i < stockVOList.getList().size(); i++) {
                    StockVO stockVO = stockVOList.getList().get(i);
                    // 未分派数
                    // Integer unallotQty =
                    // stockService.getUnallotQty(stockVO.getEntId(),
                    // stockVO.getSkuId(), stockVO.getStorId());
                    // stockVO.setUnallotQty(unallotQty);
                    // 可分派数 （正品）= 库存数-冻结数-预留数-已分派数
                    stockVO.setCanallotQty(stockVO.getSellCount() - stockVO.getAllotQty() - stockVO.getFreezeQty() - stockVO.getReserveQty());
                    // 可分派数 （次品）= 库存数-已分派数
                    stockVO.setJunkCanallotQty(stockVO.getJunkCount() - stockVO.getJunkAllotQty());
                    // 可用数 （正品）= 可分派数 （正品）-未分派数
                    stockVO.setAvailable(stockVO.getCanallotQty() - stockVO.getUnallotQty());
                }
            } else {
                // "local".equals(stockFmla.getStockValMode())
                for (int i = 0; i < stockVOList.getList().size(); i++) {
                    StockVO stockVO = stockVOList.getList().get(i);
                    // 未分派数
                    // Integer unallotQty =
                    // stockService.getUnallotQty(stockVO.getEntId(),
                    // stockVO.getSkuId(), stockVO.getStorId());
                    // stockVO.setUnallotQty(unallotQty);
                    // 库存数使用本地计算：可分派数 = 库存数(stock_qty) - 已分派数- 预留数- 冻结数-逻辑出库数
                    stockVO.setCanallotQty(stockVO.getStockQty() - stockVO.getAllotQty() - stockVO.getFreezeQty() - stockVO.getReserveQty()
                            - stockVO.getLogicStockoutQty());
                    // 可用数 （正品）= 可分派数-未分派数
                    stockVO.setAvailable(stockVO.getCanallotQty() - stockVO.getUnallotQty());
                    // 可分派数 （次品）= 库存数-已分派数
                    stockVO.setJunkCanallotQty(stockVO.getJunkQty() - stockVO.getJunkAllotQty());
                }
            }
            returnMap = getSuccessMap("查询库存信息成功");
            returnMap.put(RECORDS_FILTERED, stockVOList.getTotal());
            returnMap.put(RECORDS_TOTAL, stockVOList.getTotal());
            returnMap.put(RETURN_DATA, stockVOList.getList());
        } else {
            returnMap = getFailedMap("查询库存信息失败");
        }
        logger.info("查询库存信息结束");
        return returnMap;
    }

    /**
     * 获取企业对应项目对应仓库下系统规格的可分派数(CanallotQty:可分派数)
     *
     * @param entId
     * @param prjId
     * @param skuId
     * @param storId
     * @return
     * @throws Exception
     */
    @ResponseBody
    @RequestMapping(value = {"/getCanallotQty"})
    public Map<String, Object> getCanallotQty(String entId, String prjId, String skuId, String storId) throws Exception {
        Map<String, Object> returnMap = new HashMap<String, Object>();
        try {
            StockVO stock = stockService.getStock(entId, prjId, skuId, storId);
            if (stock != null && stock.getCanallotQty() != null) {
                returnMap.put(JSON_RESULT, SUCCESS);
                returnMap.put("canallotQty", stock.getCanallotQty().toString());// 可分派数
            } else {
                returnMap.put(JSON_RESULT, FAILED);
                returnMap.put(JSON_MSG, "获取可分派数失败");
            }

        } catch (Exception ex) {
            logUtil.error(ex.getMessage(), ex);
            returnMap.put(JSON_RESULT, FAILED);
            returnMap.put(JSON_MSG, ex.getMessage());
        }

        return returnMap;
    }

    /**
     * 更新库存（增量）
     *
     * @param stockJson 仓库SKU库存实体VO
     * @return
     * @throws Exception
     */
    @ResponseBody
    @RequestMapping(value = {"/updateStock"}, method = RequestMethod.POST, produces = "application/json; charset=utf-8")
    public Map<String, Object> updateStock(@RequestBody String stockJson) throws Exception {
        logger.info("updateStock:" + stockJson);
        Map<String, Object> returnMap = new HashMap<String, Object>();
        try {
            StockVO stockVO = JSON.parseObject(stockJson, StockVO.class);
            int effectRows = stockService.updateStock(stockVO);
            if (effectRows > 0) {
                returnMap.put(JSON_RESULT, SUCCESS);
                returnMap.put(RETURN_DATA, "");
            } else {
                returnMap.put(JSON_RESULT, FAILED);
                returnMap.put(JSON_MSG, "更新库存失败");
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            returnMap.put(JSON_RESULT, FAILED);
            returnMap.put(JSON_MSG, ex.getMessage());
        }
        return returnMap;
    }

    /**
     * 更新库存（全量）
     *
     * @param stockJson
     * @return
     * @throws Exception
     */
    @ResponseBody
    @RequestMapping(value = {"/updateStock2"}, method = RequestMethod.POST, produces = "application/json; charset=utf-8")
    public Map<String, Object> updateStock2(@RequestBody String stockJson) throws Exception {
        logger.info("updateStock2:" + stockJson);
        Map<String, Object> returnMap = new HashMap<String, Object>();
        try {
            StockVO stockVO = JSON.parseObject(stockJson, StockVO.class);
            int effectRows = stockService.updateStock2(stockVO);
            if (effectRows > 0) {
                returnMap.put(JSON_RESULT, SUCCESS);
                returnMap.put(RETURN_DATA, "");
            } else {
                returnMap.put(JSON_RESULT, FAILED);
                returnMap.put(JSON_MSG, "更新库存失败");
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            returnMap.put(JSON_RESULT, FAILED);
            returnMap.put(JSON_MSG, ex.getMessage());
        }
        return returnMap;
    }

    private Map<String, Object> getSuccessMap(String message) {
        Map<String, Object> returnMap = new HashMap<String, Object>();
        returnMap.put(JSON_RESULT, SUCCESS);
        returnMap.put(JSON_MSG, message);
        return returnMap;
    }

    ;

    private Map<String, Object> getFailedMap(String message) {
        Map<String, Object> returnMap = new HashMap<String, Object>();
        returnMap.put(JSON_RESULT, FAILED);
        returnMap.put(JSON_MSG, message);
        return returnMap;
    }

    ;

    /**
     * 验证需要导出的条件
     *
     * @param storId
     * @return
     * @throws Exception
     */
    @ResponseBody
    @RequestMapping(value = "/exportCheckStock")
    public Map<String, Object> exportCheckStock(String storId) throws Exception {
        logger.info("库存导出check：/stock/exportCheckStock");
        Map<String, Object> returnJSON = new HashMap<String, Object>();
        try {
            if (StringUtils.isBlank(storId)) {
                returnJSON.put(JSON_RESULT, FAILED);
                returnJSON.put(JSON_MSG, "请选择仓库");
                return returnJSON;
            }

            CurrentUser currentUser = WebContextFactory.getWebContext().getCurrentUser();
            if (currentUser == null) {
                returnJSON.put(JSON_RESULT, FAILED);
                returnJSON.put(JSON_MSG, "查询当前登录人失败");
                return returnJSON;
            }

            // 获取当前登录人所属项目
            String projectId = currentUser.getCurrentProject().getPrjId();
            if (StringUtils.isBlank(projectId) || currentUser.getProjectMap() == null || currentUser.getProjectMap().size() <= 0) {
                returnJSON.put(JSON_RESULT, FAILED);
                returnJSON.put(JSON_MSG, "查询当前登录人所属项目失败");
                return returnJSON;
            }

            String entId = null;
            // 找前台选择的项目，对应的企业（这种做法是为了适应，用户对应到多个企业下的情况。）
            for (ProjectVO project : currentUser.getProjectMap().values()) {
                if (project.getPrjId().equalsIgnoreCase(projectId)) {
                    entId = project.getEntId();
                }
            }

            if (StringUtils.isBlank(entId)) {
                returnJSON.put(JSON_RESULT, FAILED);
                returnJSON.put(JSON_MSG, "查询当前登录人所属企业失败");
                return returnJSON;
            }

            // 上述check都没有错误的场合
            if (returnJSON.get(JSON_RESULT) == null) {
                returnJSON.put(JSON_RESULT, SUCCESS);
            }

        } catch (Exception ex) {
            returnJSON.put(JSON_RESULT, FAILED);
            returnJSON.put(JSON_MSG, ex.getMessage());
        }
        return returnJSON;
    }

    /**
     * 导出
     *
     * @param colName
     * @param colValue
     * @param quickSearch
     * @param storId
     * @return
     * @throws Exception
     */
    @ResponseBody
    @RequestMapping(value = "/exportStock")
    public String exportStock(String colName, String colValue, String quickSearch, String storId) throws Exception {
        logger.info("查询库存信息导出：/stock/exportStock");
        try {
            StockVO queryParamVO = new StockVO();

            if (StringUtils.isBlank(quickSearch) && StringUtils.isBlank(storId)) {
                logger.error("查询库存信息导出：/stock/exportStock,缺少检索条件");
                return null;
            }
            // 获取当前登录人
            CurrentUser currentUser = WebContextFactory.getWebContext().getCurrentUser();
            if (currentUser == null) {
                logger.error("查询库存信息导出：/stock/exportStock,查询当前登录人失败");
                return null;
            }
            // 获取当前登录人所属项目
            String projectId = currentUser.getCurrentProject().getPrjId();
            if (StringUtils.isBlank(projectId) || currentUser.getProjectMap() == null || currentUser.getProjectMap().size() <= 0) {
                logger.error("查询库存信息导出：/stock/exportStock,查询当前登录人所属项目失败");
                return null;
            }
            // 设置项目id
            queryParamVO.setPrjId(projectId);

            String entId = null;
            // 找前台选择的项目，对应的企业（这种做法是为了适应，用户对应到多个企业下的情况。）
            for (ProjectVO project : currentUser.getProjectMap().values()) {
                if (project.getPrjId().equalsIgnoreCase(projectId)) {
                    entId = project.getEntId();
                }
            }
            queryParamVO.setEntId(entId);
            // 根据项目ID获取库存公式列表. 通常情况下，一个项目下只有一个库存计算公式
            StockFmla stockFmla = stockPushService.getStockFmlaByProjectId(projectId);

            // 仓库Id
            if (StringUtils.isNotBlank(storId)) {
                if ("all".equals(storId)) {
                    List<String> idArray = new ArrayList<String>();
                    // 根据项目id获取仓库信息
                    List<StorVO> storList = storService.findByProjectId(projectId);
                    for (StorVO storVO : storList) {
                        idArray.add(storVO.getStorId());
                    }
                    queryParamVO.setIdArray(idArray);
                } else {
                    queryParamVO.setStorId(storId);
                }
            }
            // 快速查询
            if (quickSearch != null && StringUtils.isNotEmpty(quickSearch)) {
                quickSearch = URLDecoder.decode(quickSearch, "UTF-8");
                if (StringUtils.isNotEmpty(quickSearch)) {
                    queryParamVO.setQuickSearch(quickSearch);
                }
            }

            String exportStatement = "";
            if (null != stockFmla && "ext".equals(stockFmla.getStockValMode())) {
                exportStatement = "";
            } else {
                exportStatement = "";
            }

            // 执行查询
            PageInfo<StockVO> stockVOList = stockService.queryStockList(0, Integer.MAX_VALUE, queryParamVO);

            if (null != stockVOList) {
                if (null != stockFmla && "ext".equals(stockFmla.getStockValMode())) {
                    for (int i = 0; i < stockVOList.getList().size(); i++) {
                        StockVO stockVO = stockVOList.getList().get(i);
                        // 未分派数
                        // Integer unallotQty =
                        // stockService.getUnallotQty(stockVO.getEntId(),
                        // stockVO.getSkuId(), stockVO.getStorId());
                        // stockVO.setUnallotQty(unallotQty);
                        // 可分派数 （正品）= 库存数-冻结数-预留数-已分派数
                        stockVO.setCanallotQty(stockVO.getSellCount() - stockVO.getAllotQty() - stockVO.getFreezeQty() - stockVO.getReserveQty());
                        // 可分派数 （次品）= 库存数-已分派数
                        stockVO.setJunkCanallotQty(stockVO.getJunkCount() - stockVO.getJunkAllotQty());
                        // 可用数 （正品）= 可分派数 （正品）-未分派数
                        stockVO.setAvailable(stockVO.getCanallotQty() - stockVO.getUnallotQty());
                    }
                } else {
                    // "local".equals(stockFmla.getStockValMode())
                    for (int i = 0; i < stockVOList.getList().size(); i++) {
                        StockVO stockVO = stockVOList.getList().get(i);
                        // 未分派数
                        // Integer unallotQty =
                        // stockService.getUnallotQty(stockVO.getEntId(),
                        // stockVO.getSkuId(), stockVO.getStorId());
                        // stockVO.setUnallotQty(unallotQty);
                        // 库存数使用本地计算：可分派数 = 库存数(stock_qty) - 已分派数- 预留数- 冻结数-逻辑出库数
                        stockVO.setCanallotQty(stockVO.getStockQty() - stockVO.getAllotQty() - stockVO.getFreezeQty() - stockVO.getReserveQty()
                                - stockVO.getLogicStockoutQty());
                        // 可用数 （正品）= 可分派数-未分派数
                        stockVO.setAvailable(stockVO.getCanallotQty() - stockVO.getUnallotQty());
                        // 可分派数 （次品）= 库存数-已分派数
                        stockVO.setJunkCanallotQty(stockVO.getJunkQty() - stockVO.getJunkAllotQty());
                    }
                }
            }
            exportExcelFile(stockVOList.getList(), colName, colValue, "库存查询导出");

        } catch (Exception ex) {
            ex.printStackTrace();
            logger.error(ex.getMessage());
        }
        return null;
    }

    /**
     * 查询第三方仓库的库存的商品（带批次，效期）
     *
     * @return 结果Map
     * @throws Exception 异常
     */
    @ResponseBody
    @RequestMapping(value = "/getSkuList")
    public Map<String, Object> getSkuList(String formJson) {

        Map<String, Object> returnMap = new HashMap<String, Object>();

        try {
            // 获取当前登录人
            CurrentUser currentUser = WebContextFactory.getWebContext().getCurrentUser();
            if (currentUser == null) {
                logger.error("查询库存信息导出：/stock/getSkuList,查询当前登录人失败");
                return null;
            }
            // 获取当前登录人所属项目
            String projectId = currentUser.getCurrentProject().getPrjId();

            String entId = null;
            // 找前台选择的项目，对应的企业（这种做法是为了适应，用户对应到多个企业下的情况。）
            for (ProjectVO project : currentUser.getProjectMap().values()) {
                if (project.getPrjId().equalsIgnoreCase(projectId)) {
                    entId = project.getEntId();
                }
            }
            if (StringUtils.isBlank(entId)) {
                logger.error("查询库存信息导出：/stock/getSkuList,查询当前登录人企业失败");
                return null;
            }

            formJson = URLDecoder.decode(formJson, "UTF-8");
            Map<String, Object> formMap = (Map<String, Object>) JSON.parse(formJson);
            StockVO param = new StockVO();
            if (formMap == null) {
                logger.error("查询库存信息导出：/stock/getSkuList,缺少仓库ID");
                return null;
            }
            if (StringUtils.isBlank((String) formMap.get("storId"))) {
                logger.error("查询库存信息导出：/stock/getSkuList,缺少仓库ID");
                return null;
            }
            param.setStorId((String) formMap.get("storId"));
            param.setEntId(entId);
            if (StringUtils.isNotBlank((String) formMap.get("goodsCode"))) {
                param.setGoodsCode((String) formMap.get("goodsCode"));
            }

            if (StringUtils.isNotBlank((String) formMap.get("goodsName"))) {
                param.setGoodsName((String) formMap.get("goodsName"));
            }

            if (StringUtils.isNotBlank((String) formMap.get("skuCode"))) {
                param.setSkuCode((String) formMap.get("skuCode"));
            }

            if (StringUtils.isNotBlank((String) formMap.get("skuName"))) {
                param.setSkuName((String) formMap.get("skuName"));
            }

            // 排序语句生成
            Map<String, String> replaceFieldsMap = new HashMap<String, String>();
            String orderStatement = getOrderString(IStockDAO.class.getName(), "selectSkuList", replaceFieldsMap);
            param.setOrderBy(orderStatement);
            List<StockVO> list = stockService.getSkuList(param);

//            PrjSkuVO prjSkuVO = JSONObject.parseObject(formJson, PrjSkuVO.class);
//            CurrentUser currentUser = WebContextFactory.getWebContext().getCurrentUser();
//            String projectId = currentUser.getCurrentProject().getPrjId();
//            prjSkuVO.setPrjId(projectId);
//            if ("n".equals(prjSkuVO.getIsGift())) {
//                prjSkuVO.setIsGift("w");
//            }
//
//            List<PrjSkuVO> prjSkuVOList = goodsServiceImpl.selectPrjSkuListForStockIn(prjSkuVO);

            returnMap.put(JSON_RESULT, SUCCESS);
            returnMap.put(RETURN_DATA, list);
        } catch (Exception ex) {
            logger.error(ex.getMessage(), ex);
            returnMap.put(JSON_RESULT, FAILED);
            returnMap.put(JSON_MSG, ex.getMessage());
        }

        return returnMap;
    }

    /**
     * 更新 批次库存（增量）
     *
     * @param stockJson
     * @return
     * @throws Exception
     */
    @ResponseBody
    @RequestMapping(value = {"/updateBatchStock"}, method = RequestMethod.POST, produces = "application/json; charset=utf-8")
    public Map<String, Object> updateBatchStock(@RequestBody String stockJson) throws Exception {
        logger.info("updateBatchStock:" + stockJson);
        Map<String, Object> returnMap = new HashMap<String, Object>();
        try {
            BatchStockVO batchStockVO = JSON.parseObject(stockJson, BatchStockVO.class);
            int effectRows = stockService.updateBatchStock(batchStockVO);
            if (effectRows > 0) {
                returnMap.put(JSON_RESULT, SUCCESS);
                returnMap.put(RETURN_DATA, "");
            } else {
                returnMap.put(JSON_RESULT, FAILED);
                returnMap.put(JSON_MSG, "增量更新批次库存失败");
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            returnMap.put(JSON_RESULT, FAILED);
            returnMap.put(JSON_MSG, ex.getMessage());
        }
        return returnMap;
    }
}
